// ==UserScript==
// @name		Naviextras
// @version		1.0.14
// @description	NNG helper
// @author		isvorcz
// @namespace   NNG
// @include		http://*.navngo.local/*
// @include		https://*.navngo.local/*
// @include		http://*.naviextras.com/*
// @include		https://*.naviextras.com/*
// @include		https://*.bibit.com/*
// @include		http://*.navigation.com/*
// @include		https://*.navigation.com/*
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_log
// @grant       GM_deleteValue
// @grant       GM_xmlhttpRequest
// @grant       GM_getResourceText
// @require     http://nnghelper.googlecode.com/svn/trunk/naviextras/jquery-2.1.1.min.js
// @require     http://nnghelper.googlecode.com/svn/trunk/naviextras/jquery-ui.1.10.4.min.js
// @require		http://nnghelper.googlecode.com/svn/trunk/naviextras/jquery-floating.js
// @require		http://nnghelper.googlecode.com/svn/trunk/naviextras/jquery.json-2.2.min.js
// ==/UserScript==

var VERSION_STR = 'v1.0.14'
var VERSION_DATE = '2015-03-03';
var VERSION_JSON = {base : "http://cms.edit.naviextras.com/opencms/opencms/shop/helper/", changeLog: [], write:1};
var VERSION_PATTERN = /^v(\d+)\.(\d+)\.(\d+)(\.(\d+)|[a-z].*|)$/i;
var VERSION = {major:1, minor:0, build:0};
var MAIN_ICON = 'clock';
var TIME_PATTERN  = /^\s*(\d{1,2}):(\d{1,2})\s*$/;
var KEY_OPTIONS = 'nngOptions';
var KEY_PROJECTS = 'nngProjects';
var KEY_VERSION = 'nngVersion';
var KEY_CONFIG = 'nngHConfig';
var KEY_STATUS = 'nngStatus';
var KEY_TRACKED = 'tracked';
var KEY_TTDATA = 'ttData';
var KEY_LOGKEY = "cmsKeyLogger"
var TAB_SETTINGS = 'settings';
var TAB_PROJECTS = 'projects';
var TAB_DAY = 'editDay';
var TAB_HIDDEN = 'hidden';
var TAB_ABOUT = 'about';
var TAB_CHANGELOG = 'changelog';
var TAB_TTDATA = 'ttd';

var TYPE_MANTIS = 'm';
var TYPE_PROJECT = 'tt';
var TYPE_CODEREVIEW = 'cr';
var TYPE_TASK = 'tr';

var ACTIVATE_PIC = 'activate';
var DEACTIVATE_PIC = 'deactivate';
var SETUP_PIC = 'wizard';
var DAY = 86400000;

var base;
var thisMantis = {id:0,type:TYPE_MANTIS};

var options = {};
var optionsDefault = {
	projects : [757, 759, 760, 761, 762, 758, 770, 763] ,
	workTime : {start : '9:00', end: '17:20'},
	uitheme: 'base'
}

var UITHEMES = ['base', 'black-tie', 'blitzer', 'cupertino', 'dark-hive',
	'dot-luv', 'eggplant', 'excite-bike', 'flick', 'hot-sneaks',
	'humanity', 'le-frog', 'mint-choc', 'overcast', 'pepper-grinder',
	'redmond', 'smoothness', 'south-street', 'start', 'sunny',
	'swanky-purse', 'trontastic', 'ui-darkness', 'ui-lightness', 'vader'];

var isChrome = false;
try  {
	isChrome = chrome != null && chrome != undefined && chrome.runtime != null;
} catch (e) {
}

var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date)) throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};


GM_log('isChrome:'+isChrome);

var log = 'isChrome:'+isChrome

var scriptJQ;

if (!isChrome) {
	window.addEventListener('load', function(){var checker=setInterval(function(){
	        if(typeof (scriptJQ = jQuery.noConflict()) != "undefined") {
	                clearInterval(checker);
	                naviextras();
	        }
	},100);}, false);
}

var exportDates;

function parseVersion(s) {
    var m = VERSION_PATTERN.exec(s);
    var result = {major:1, minor:0, build:0};
    if (m) {
        var rev = m[4] && m[4].indexOf("\.", 0)==0 ? m[4].substr(1): m[4];
        result = {major:m[1]*1, minor:m[2]*1, build:m[3]*1, revision:rev};
    }
    GM_log('parseVersion:'+scriptJQ.toJSON(result)+'|'+s);
    return result;
}

function isNewerVersion(v1, v2) {
    var result = false;
    if (v2.major > v1.major) {
        result = true;
    } else if (v2.major < v1.major) {
        result = false;
    } else if (v2.minor > v1.minor) {
        result = true;
    } else if (v2.minor < v1.minor) {
        result = false;
    } else if (v2.build > v1.build) {
        result = true;
    } else if (v2.build < v1.build) {
        result = false;
    } else if (v1.revision == null || v1.revision == undefined) {
        result = false;
    } else if (v2.revision == null || v2.revision == undefined) {
        result = true;
    }
    return result;
}

function naviextras() {
	realMain();
}

var scriptJQ = jQuery== undefined ? $ : jQuery.noConflict();

function realMain() {
    var HREF = location.href;
    var parts = HREF.split('/');
    if (HREF.indexOf("http://")!=0 && HREF.indexOf("https://")!=0) {
        GM_log('return:'+HREF);
        return;
    }
    site = parts[2];
    VERSION = parseVersion(VERSION_STR);
    
    GM_log(log);

    readOptions();
	var uiCSSexists = parts[5] && parts[5].indexOf('deviceSelect')==0;
	
    scriptJQ('head style').each(function () {
		uiCSSexists |= scriptJQ(this).text().match(/jquery-ui.*css/i)!=null;
	});
    scriptJQ('head link[href*="jquery-ui"]').each(function () {
		uiCSSexists = true;
	});
	if (!uiCSSexists) {
		scriptJQ('head').append('<style id="naviextrasHelperTheme">@import "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/'+options.uitheme+'/jquery-ui.css";</style>');
	}
    scriptJQ('head').append('<style>'
//    +'.ui-autocomplete a.ui-corner-all { font-size: 12px; }'
//    +'.ui-autocomplete { max-height: 300px; overflow-y: auto;	overflow-x: hidden;	padding-right: 20px; }'
    +'#nngChangeLog { font-size: 12px; }'
    +'#nngMantisToolbar { text-align:left; }'
    +'#cmsDialog { font-size: 12px; }'
    +'#nehelper { position: absolute; border: 1px solid #c93;'
	+'  padding: 2px;	background: #ffc;'
	+'  font: 11px tahoma, arial, helvetica, sans-serif;'
	+'  color: #444;	text-align: left; left: -1px; z-index:1;}'
    +'</style>');

    console.log(parts[2]+":"+parts[3]);
    if (parts[3]==='shop'&&parts[4]==='portal') {
        initShop(parts);
    } else if (parts[3]==="shopAdmin") {
        initShopAdmin(parts);
    } else if (parts[2].match('worldpay.com$')){
        initBibit(parts);
    } else if (parts[2].match('bibit.com$')){
        initBibit(parts);
    } else if (parts[2].match('navigation.com$')){
        initNavteq(parts);
	} else {
		console.log(parts[2].match('worldpay.com$'));
	}
	readConfigCallback();
}
var site;

var channelName = "";
var nelang = 'en';
var nestate = 'normal';
var ip = '127.0.0.1';
var ipLast = '1';

function findUserChange() {
	var filterPattern = scriptJQ(this).val();
	scriptJQ('#findUserFilter').hide();
	if (/^\s*[A-Z]{4}0{6}[0-9]{18}[0-9A-F]{4}\s*$/.test(filterPattern)) {
		console.log('trID:'+filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=TRANSACTION_ID]').prop('selected',true);
	} else if (/@/.test(filterPattern)) {
		console.log('mail:'+filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=USER_EMAIL]').prop('selected',true);
	} else if (/^[0-9]+$/.test(filterPattern)) {
		console.log('DEVICE_CODE:'+filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=DEVICE_CODE]').prop('selected',true);
	} else if (/^\s*[A-Z0-9]{16}\s*$/.test(filterPattern)) {
		var match = /^\s*([A-Z0-9]{4})([A-Z0-9]{4})([A-Z0-9]{4})([A-Z0-9]{4})\s*$/.exec(filterPattern);
		console.log('ID:'+filterPattern);
		filterPattern = 'CK-'+match[1]+'-'+match[2]+'-'+match[3]+'-'+match[4];
		scriptJQ(this).val(filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=DEVICE_SWID]').prop('selected',true);
	} else if (/^\s*CK-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}\s*$/.test(filterPattern)) {
		console.log('SWID:'+filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=DEVICE_SWID]').prop('selected',true);
	} else if (/^\s*C[PW]-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}\s*$/.test(filterPattern)) {
		console.log('LIC:'+filterPattern);
		scriptJQ('#findUser select[name=searchType] option[value=PRODUCT_LICENSE_CODE]').prop('selected',true);
	} else {
		var possible = ['USER_FULLNAME','PREPAID_CODE','STICKER','DEVICE_NAME','EXTERNAL_ID','EXT_TRANSACTION_ID','VIN'];
		//scriptJQ('#findUserFilter').html('');
		if (/^[a-zA-Z](_?[a-zA-Z0-9])+$/.test(filterPattern)) {
			possible.push('USER_NAME');
		}
		if (/^[0-9]+$/.test(filterPattern)) {
			possible.push('USER_ID');
			possible.push('DEVICE_CODE');
			possible.push('DEVICE_IMEI');
		}
		if (/^[A-Z]{4}[0-9]+$/.test(filterPattern)) {
			possible.push('INVOICE_NUMBER');
		}
		console.log(possible);
		scriptJQ('#findUserFilter').html(''+possible);
		scriptJQ('#findUserFilter').show();
	}
	scriptJQ.cookie("searchType",scriptJQ('#findUser select[name=searchType]').val());
}

function initUserAdmin() {
	console.log('initUserAdmin');
	scriptJQ('#findUser input[name=pattern]').change(findUserChange);
	scriptJQ('#findUser').append('<div id="findUserFilter" style="display:none"></div>');
	if (scriptJQ.cookie("searchType")) {
		scriptJQ('#findUser select[name=searchType] option[value='+scriptJQ.cookie("searchType")+']' ).prop('selected',true);
	}
	scriptJQ('#findUser').submit(function () {
		console.log(scriptJQ('#findUser select[name=searchType]').val());
		scriptJQ.cookie("searchType",scriptJQ('#findUser select[name=searchType]').val());
	});
}

function initShop(parts) {
	base = parts[0]+'//'+parts[2]+'/'+parts[3]+'/'+parts[4]+'/';
	console.log('initShop:'+scriptJQ('#findUser input[name=pattern]').size());
	if (scriptJQ('#findUser input[name="pattern"]').size()>0) {
		initUserAdmin();
	}
	readStatus(function(v) {
		if (v) {
			if (v.lang) {
				nelang = v.lang;
			}
			if (v.ip) {
				ip = v.serverIp;
				ipLast = v.serverIp.replace(/.*\./,"");
			}
			if (v.mode) {
				nestate = v.mode;
			}
			if (v.channelName) {
				channelName = v.channelName;
			}
			refreshMain();
		}
	});
    var domain = parts[2].substring(0,parts[2].indexOf('\.')-1);         
    var menuLanguage = scriptJQ("label[for='langcombo']").text();
	scriptJQ("body").prepend('<span id="nehelper">\
	<span class="ui-icon '+(getValue('showTable','none')=='none'?'ui-icon-folder-collapsed':'ui-icon-folder-open')
	+'" id="showTable"></span>\
	<table cellpadding="0" cellspacing="0" style="width:100%; display:'
	+getValue('showTable','none')+'" id="neMainTable">\
	<tr><th>Lang: </th><td>\
	<select id="nelang" style="width:100%"></select></td></tr>\
	<tr><th>Keys: </th><td><select id="nestate" style="width:100%">\
	<option value="normal">Normal</option>\
	<option value="cmstag">CMS Tag</option>\
	<option value="keys">Keys</option>\
	<option value="full">Full</option>\
	</select></td></tr>\
	<tr><th>Mode: </th><td><select id="nemode" style="width:100%">\
	<option value="normal">Normal</option>\
	<option value="toolbox">Toolbox</option>\
	<option value="iframe">Iframe</option>\
	</select></td></tr>\
	<tr><th>Channel:</th><td><span id="channel">???</span></td></tr>\
	<tr><th>Now:</th><td><span>'+(new Date()).format("isoDateTime")+'</span></td></tr>\
	<tr class="infoRow"><th colspan="2" align="center" style="text-decoration: underline;">Info</th></tr>\
	<tr class="nqDebug" style="display:none"><th colspan="2" align="center" style="text-decoration: underline;">Navteq</th></tr>\
	<tr id="logKeys" style="text-decoration: underline;display:none;""><th colspan="2" align="center">Start Log</th></tr>\
	<tr class="systemRow"><th>System:</th><td><span id="system" style="text-decoration: underline;"></span></td></tr>\
	<tr class="systemRow"><th>Server:</th><td><span id="server" style="text-decoration: underline;"></span> (<span id="ip">???</span>)</td></tr>\
	<tr><th align="center" id="neVersion" colspan="100%" title='+VERSION_DATE+'>'+VERSION_STR+'</th></tr>\
	<tr style="display:none" id="nehNewsletterTR"><td colspan="100%">\
	<span id="nlSaveAdvert" style="cursor:pointer; text-decoration: underline;">Save Advert</span>\
	<br/><span id="nlUseAdvert" style="cursor:pointer; display:none; text-decoration: underline;">Use Advert</span>\
	<br/><span id="nlConfigNE" style="cursor:pointer; text-decoration: underline;">Naviextras</span>\
	<br/><span id="nlConfigMA" style="cursor:pointer; text-decoration: underline;">Mappy</span>\
	<br/><span id="nlConfigZE" style="cursor:pointer; text-decoration: underline;">Zenec</span>\
	<br/><span id="nlConfigUNAV" style="cursor:pointer; text-decoration: underline;">Unav</span>\
	</td></tr>\
	<tr id="nehServersTR" style="display:none"><td colspan="100%">\
	<span id="nlServers" style="cursor:pointer; text-decoration: underline;">Servers</span>\
	</td></tr>\
	</table>\
	</span><div id="cmsDialog" title="Content info"/>\
	<div id="systemDialog" title="System info"/>\
	<div id="infoDialog" title="Debug info"/>\
	<div id="nqDialog" title="Debug info"/>\
	<form method="post" action="'+location.href+'" style="display:none" id="neHiddenForm">\
	<input id="neSpecParam"/><br/>\
	</form>');
	try {
	scriptJQ('#logKeys').css('cursor','pointer').click(function () {
		var log = GM_getValue(KEY_LOGKEY);
		if (log) {
			GM_log('logKeys off');
			var keyMap = JSON.parse(log);
			var keys = "";
			for(var k in keyMap) {
				keys += "|"+k;
			}
			GM_log('keys on page:'+keys);
			GM_deleteValue(KEY_LOGKEY);
			scriptJQ('#logKeys th').text('Log keys');
		} else {
			console.log('logKeys on');
			var keyMap = {};
			scriptJQ('span.cmsTag, span.CMSTAG').each(function () {
				keyMap[scriptJQ(this).attr('liveid')]="1";
			});
			GM_setValue(KEY_LOGKEY, JSON.stringify(keyMap));
			scriptJQ('#logKeys th').text('Dump keys');
		}
	});
	} catch (e) {
		GM_log("eeeeeeeeeee:"+e);
	}

	scriptJQ('#nlServers').css('cursor','pointer').click(function() {
		html = '<textarea style="width:450px; height:200px;font-family: monospace; font-size:10px">';
		for(var sys in config.systems) {
			if (config.systems[sys].servers) {
				for (var key in config.systems[sys].servers) {
					html += "#mkdir -p "+sys+"\n"
					html += "scp simpla@"+ config.systems[sys].servers[key].host+":/home/"+config.systems[sys].servers[key].usr+"/setup.properties "+sys+"\n";
					html += "#scp simpla@"+ config.systems[sys].base+":/home/"+config.systems[sys].servers[key].usr+"/etc/*.htconf "+sys+"\n";
					break;
				}
			}
		}
		html += '</textarea>'
		scriptJQ('#infoDialog').html(html).dialog( "open" );
		
		/*
		"iop" :	{ 
			base : "iop.demo.naviextras.com",
			servers : {
				'bike' : { ip : 106, host : 'bike1.dev.naviextras.com', ports:[11080,11081], usr: 'extrone' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}

		*/
	});
	
	if (location.href.match(/newsletterAdmin/)) {
		scriptJQ('#nehNewsletterTR').show();
		if (getValue('nlAdvert')!=null) {
			scriptJQ('#nlUseAdvert').show();
		}
		scriptJQ('#nlSaveAdvert').click(function () {
			setValue('nlAdvert',scriptJQ('#eladnivalo').html());
			scriptJQ('#nlUseAdvert').show();
		});
		scriptJQ('#nlUseAdvert').click(function () {
			scriptJQ('#eladnivalo').html(getValue('nlAdvert'));
		});
		/*
	<br/><span id="nlConfigNE" style="cursor:pointer; text-decoration: underline;">Naviextras</span>\
	<br/><span id="nlConfigMA" style="cursor:pointer; text-decoration: underline;">Mappy</span>\
	<br/><span id="nlConfigZE" style="cursor:pointer; text-decoration: underline;">Zenec</span>\
	*/
		scriptJQ('#nlConfigNE').click(function () {
			scriptJQ('#selectedChannels option').each(function () {
				if (/ (naviextras.com|aftermarket-(nq|ta)|navteq|airis(-nq)?|telesystem(-nq)?)/.test(scriptJQ(this).text())) {
					scriptJQ(this).attr('selected','selected');
				} else {
					scriptJQ(this).removeAttr('selected');
				} 
			});
			scriptJQ('#selectedLanguages option').each(function () {
				if (/(hu|de|fr|pt|it|tr)/.test(scriptJQ(this).attr('value'))) {
					scriptJQ(this).removeAttr('selected');
				} else {
					scriptJQ(this).attr('selected','selected');
				} 
			});
			scriptJQ('#lowerIgoVersion').attr('value','IGO8R3');
		});
		scriptJQ('#nlConfigZE').click(function () {
			scriptJQ('#selectedChannels option').each(function () {
				if (/ zenec(-nq)?/.test(scriptJQ(this).text())) {
					scriptJQ(this).attr('selected','selected');
				} else {
					scriptJQ(this).removeAttr('selected');
				}
			});
			scriptJQ('#selectedLanguages option').each(function () {
				if (/(de)/.test(scriptJQ(this).attr('value'))) {
					scriptJQ(this).removeAttr('selected');
				} else {
					scriptJQ(this).attr('selected','selected');
				} 
			});
			scriptJQ('#lowerIgoVersion').attr('value','IGO8R3');
		});
		scriptJQ('#nlConfigMA').click(function () {
			scriptJQ('#selectedChannels option').each(function () {
				if (/ mappy(-nq)?/.test(scriptJQ(this).text())) {
					scriptJQ(this).attr('selected','selected');
				} else {
					scriptJQ(this).removeAttr('selected');
				}
			});
			scriptJQ('#selectedLanguages option').each(function () {
				if (/(fr)/.test(scriptJQ(this).attr('value'))) {
					scriptJQ(this).removeAttr('selected');
				} else {
					scriptJQ(this).attr('selected','selected');
				} 
			});
			scriptJQ('#lowerIgoVersion').attr('value','IGO8R3');
		});
		scriptJQ('#nlConfigUNAV').click(function () {
			scriptJQ('#selectedChannels option').each(function () {
				if (/ becker(-nq)?/.test(scriptJQ(this).text())) {
					scriptJQ(this).attr('selected','selected');
				} else {
					scriptJQ(this).removeAttr('selected');
				}
			});
			scriptJQ('#selectedLanguages option').each(function () {
				if (/(de)/.test(scriptJQ(this).attr('value'))) {
					scriptJQ(this).removeAttr('selected');
				} else {
					scriptJQ(this).attr('selected','selected');
				} 
			});
		});
	}
	
	scriptJQ('tr.systemRow').css('cursor','pointer').click(function() { 
		var html = 'No state info!';
		var now = new Date();
		html = '<div style="width:450px; font-family: monospace; font-size:10px; text-align:left;">';
		try {
			html +='<b>System</b>: '+system +' (base:'+config.systems[system].base+')<br/>\n';
			html +='<b>DB</b>: '+config.systems[system].db.usr+'@'+config.systems[system].db.host
			     + ':' +config.systems[system].db.port+'  prefix:' +config.systems[system].db.prefix+'<br/>\n';
			for(var sys in config.systems[system].servers) {
				var s = config.systems[system].servers[sys];
				html +='<span '+(sys==server?'style="font-weight:bold;"':'')+'>Server '
				+sys+':</span> ip:'+s.ip+', '+s.usr+'@'+s.host;
				for(var i in s.ports) {
					var p = s.ports[i];
					html += ' <a href="' + (p%10==0 ? 'http://' : 'https://') +s.host+":"+s.ports[i]+'/shop/" target="_blank">'+s.ports[i]+'</a> '
				}
				html += '<br/>';
			}
		} catch (e) {
			 html += e;
		}
		html +='</div>';
		scriptJQ('#systemDialog').html(html).dialog( "open" );
	});

	scriptJQ('tr.infoRow').css('cursor','pointer').click(function() {
		var html = 'No state info!';
		if (STATUS_JSON) {
			var now = new Date();
			html = '<textarea style="width:450px; height:200px;font-family: monospace; font-size:10px">\
Agent: '+navigator.userAgent+'\n\
URL: '+location.href+'\n\
Date: '+now+'\n\
User: '+STATUS_JSON.user+' ('+STATUS_JSON.ip+')\n\
Channel: '+STATUS_JSON.channelName+'\n\
Lang: '+STATUS_JSON.lang+'\n\
System: '+system+'\n\
Server: '+server+' ('+STATUS_JSON.serverIp+')\n\
Mode: '+STATUS_JSON.mode+'\n\n';
			if (STATUS_JSON.shopRevision) {
				html +='SHOP:SHOP-IMPL\n\
===============\n\
Version: '+STATUS_JSON.shopVersion+'\n\
Revision: '+STATUS_JSON.shopRevision+'\n\
Build Time: '+new Date(STATUS_JSON.shopTimestamp*1)+':'+STATUS_JSON.timestamp+'\n\
Scm: '+STATUS_JSON.shopScm+'\n\n';
			}
			html +='META:PRODUCTION\n\
===============\n\
Version: '+STATUS_JSON.version+'\n\
Revision: '+STATUS_JSON.revision+'\n\
Build Time: '+new Date(STATUS_JSON.timestamp*1)+':'+STATUS_JSON.timestamp+'\n\n\
DEPENDENCIES\n\
============\n';
			try {
				for(var i in STATUS_JSON.dependencies) {
					var d = STATUS_JSON.dependencies[i];
					html += d.artifactId+' '+d.version+" ("+d.type+")\n";
				}
			} catch (e) {
				html += 'Dependency info not found';
			}
			html += '</textarea>';
		} 
		scriptJQ('#infoDialog').html(html).dialog( "open" );
	});
	
	scriptJQ('#showTable').click(function() {
		scriptJQ('#neMainTable').toggle();
		var display = scriptJQ('#neMainTable').css('display');
		setValue('showTable',display);
		if (display=='none') {
			scriptJQ('#showTable').removeClass('ui-icon-folder-open').addClass('ui-icon-folder-collapsed');
		} else {
			scriptJQ('#showTable').removeClass('ui-icon-folder-collapsed').addClass('ui-icon-folder-open');
		}
	});
	if (scriptJQ('span.cmsTag').size()>0) {
		nestate = 'cmstag';
		scriptJQ('span.cmsTag, span.CMSTAG').text('(X)').css('font-size','8px')
			.css('cursor','pointer').click(showContentInfo);
		scriptJQ('#logKeys').show();
		var log = GM_getValue(KEY_LOGKEY);
		if (log) {
			console.log('logKeys off');
			var keyMap = JSON.parse(log);
			scriptJQ('span.cmsTag, span.CMSTAG').each(function () {
				keyMap[scriptJQ(this).attr('liveid')]="1";
			});
			GM_setValue(KEY_LOGKEY, JSON.stringify(keyMap));
			scriptJQ('#logKeys th').text('Dump keys');
		} else {
			scriptJQ('#logKeys th').text('Log keys');
		}

	} else if (menuLanguage.indexOf('menuLanguage')==0) {
		if (menuLanguage.indexOf('$')>0) {
			nestate = 'full';
		} else {
			nestate = 'keys';
		}
	} else {
//		trackerEngineHeader$naviextras.com.Descr
		var body = scriptJQ('body').text().trim().substring(0,60);
		if (body.indexOf('trackerEngineHeader$')>=0) {
			nestate = 'full';
			var ch = body.substring(body.indexOf('\$')+1);
			channelName = ch.substring(0,channel.indexOf('.Description'));
		} else {
			if (body.indexOf('trackerEngineHeader')>=0) {
				nestate = 'keys';
			} else {
				nestate = 'normal';
			}
		}
	}

	scriptJQ('#channel').text(channelName);
	scriptJQ('#cmsDialog').dialog({
		autoOpen: false,
		show: "blind",
		hide: "explode",
		minWidth: 150
	});
	
	scriptJQ('#systemDialog').dialog({
		autoOpen: false,
		show: "blind",
		hide: "explode",
		minWidth: 500
	});
	
	scriptJQ('#infoDialog').dialog({
		autoOpen: false,
		show: "blind",
		hide: "explode",
		minWidth: 500
	});
	
	scriptJQ('#nqDialog').dialog({
		autoOpen: false,
		show: "blind",
		hide: "explode",
		minWidth: 800
	});
	
	var p = scriptJQ('#sn').text().split('|');
	if (p.length >= 2) {
		ipLast = p[0].replace(/ /g,'');
		channelName = p[1];
		showSystem(p[0].replace(/ /g,'')*1, parts[2]);
	} else {
		showSystem(1, parts[2]);
	}

	var langSelect = scriptJQ('select[name="live.ui.locale.code.request"]');
	if (langSelect.size()>0) {
		nelang = langSelect.val();
//	} else if (scriptJQ('span.cmsTag').size()>0) {
	}

	scriptJQ('#nestate option[value="'+nestate+'"]').attr('selected','selected');
	var nemode =scriptJQ('#sn').size()>0?'normal':'toolbox';
	scriptJQ('#nemode option[value="'+nemode+'"]').attr('selected','selected');
	
	scriptJQ('#nehelper').show();
	
	scriptJQ('#nestate').change(
		function () {
			scriptJQ('#neSpecParam').attr('name','live.mode.showkeys').attr('value',scriptJQ(this).val());
			scriptJQ('#neHiddenForm').submit();
		}
	);	
	scriptJQ('#nelang').change(
		function () {
			scriptJQ('#neSpecParam').attr('name','live.ui.locale.code').attr('value',scriptJQ(this).val());
			scriptJQ('#neHiddenForm').submit();
		}
	);	
	scriptJQ('#nemode').change(
		function () {
			scriptJQ('#neSpecParam').attr('name','live.mode').attr('value',scriptJQ(this).val());
			scriptJQ('#neHiddenForm').submit();
		}
	);	
	refreshMain();
}
	
function refreshMain() {
	console.log('refreshMain');
	scriptJQ('#ip').text(ipLast);
	scriptJQ('#channel').text(channelName);
	if (channelName.indexOf('subaru')>=0 || channelName.indexOf('boss3-nq')>=0 || channelName.indexOf('becker')>=0) {
		scriptJQ('tr.nqDebug').show().css('cursor','pointer').click(function() {
			var html = 'Missing NQ Debug info';
			scriptJQ.ajax({
				type: 'GET',
				url: '/shop/nqdebug?time='+(new Date()).getTime(),
				error:function( a, b, c ) {
					console.log('setStatus error:'+a+','+b+','+c);
					scriptJQ('#infoDialog').html('setStatus error:'+a+','+b+','+c).dialog( "open" );
				},
				success: function( data ) {
					console.log(data)
					html = '<h3>Transaction: '+scriptJQ(data).attr('transaction')+', state:'+scriptJQ(data).attr('state')+'</h3>';
					html += '<table width="???100%">';
					scriptJQ('nqlog > log',data).each(function (i) {
							html += '<tr><th valign="top" title="'+(new Date(scriptJQ(this).attr('date')*1))+'">'+i+':'+scriptJQ(this).attr('type')+'</th><td align="left">';
							html += scriptJQ(this).text().replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br/>\n').replace(/ /g,'&nbsp;\n');
							html += '</td></tr>';
							
						}
					); 
 					html += '</table>';
					scriptJQ('#nqDialog').html(html).dialog( "open" );
				},
				dataType: 'xml'
			});
		});
	}

	scriptJQ('#nelang').html('');
	for(var k in config.languages) {
		scriptJQ('#nelang').append('<option value="'+k+'">'+config.languages[k]+'</option>');
	}
	/*
	for(var k in config.admins) {
		scriptJQ('#neadmin').append('<option value="'+config.admins[k]+'">'+k+'</option>');
	}
	*/
	scriptJQ('#nelang option[value="'+nelang+'"]').attr('selected','selected');
	/*
	scriptJQ('#neadmin').change(
		function () {
			if (scriptJQ(this).val()!="NA") {
				location.href=base+scriptJQ(this).val();
			}
		}
	);
	*/	
}

function setValue(key, value) {
	GM_setValue(key, value);
}

function getValue(key, def) {
	return GM_getValue(key, def);
}

function readVersion(callBack) {
    GM_log('readVersion');
	VERSION_JSON  =  eval('('+getValue(KEY_VERSION,'{"base" : "http://cms.edit.naviextras.com/opencms/opencms/shop/helper/", changeLog: [], write:1}')+')');
	if (isChrome) {
		callBack(VERSION_JSON);
		chrome.runtime.sendMessage({action:"getVersion"}, function (v) {
			VERSION_JSON = scriptJQ.evalJSON(v);
			callBack(VERSION_JSON);
		});
	} else {
		callBack(VERSION_JSON);
		if (refresh(VERSION_JSON, 1800)) {
			GM_xmlhttpRequest({method: 'GET',
			     url: 'http://cms.edit.naviextras.com/opencms/opencms/shop/helper/version.json?time='+(new Date()).getTime(),
			     headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
			              'Accept': 'application/json'
				 },
				 onload: function(responseDetails) {
					var data = responseDetails.responseText;
                    GM_log('readVersion.onLoad');
					VERSION_JSON = eval('('+data+')');
					GM_setValue(KEY_VERSION, data);
					VERSION_JSON.write = (new Date()).getTime()
					callBack(VERSION_JSON);
				 },
                 onerror: function(responseDetails) {
                    GM_log(scriptJQ.toJSON(responseDetails));
                 }
			});
		} else {
			GM_log('hold fire');
		}
	};
	return VERSION_JSON;
}

function readStatus(callBack) {
    GM_log('readStatus');
	STATUS_JSON  =  eval('('+getValue(KEY_STATUS,'{ write:1}')+')');
	if (isChrome) {
		scriptJQ.ajax({
			type: 'GET',
			url: base+'../status?time='+(new Date()).getTime(),
			error:function( a, b, c ) {
				console.log('setStatus error:'+a+','+b+','+c);
			},
			success: function( data ) {
				console.log('getStatus.success:'+scriptJQ.toJSON(data));
				STATUS_JSON = data;
				STATUS_JSON.write = (new Date()).getTime();
				callBack(data);
				//sendResponse(data);
			},
			dataType: 'json'
		});
	} else {
		callBack(STATUS_JSON);
		if (refresh(STATUS_JSON, 1800)) {
			GM_xmlhttpRequest({method: 'GET',
			     url: '../status?time='+(new Date()).getTime(),
			     headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
			              'Accept': 'application/json'
				 },
				 onload: function(responseDetails) {
					var data = responseDetails.responseText;
                    GM_log('readVersion.onLoad');
					STATUS_JSON = scriptJQ.evalJSON(data);
					GM_setValue(KEY_STATUS, data);
					STATUS_JSON.write = (new Date()).getTime();
					callBack(STATUS_JSON);
				 },
                 onerror: function(responseDetails) {
                    GM_log(scriptJQ.toJSON(responseDetails));
                 }
			});
		} else {
			GM_log('hold fire');
		}
	};
	return VERSION_JSON;
}
function readConfig(callBack) {
	GM_log('readConfig');

	if (isChrome) {
		chrome.runtime.sendMessage({action:"getStatus", urlBase: base}, function (v) {
			console.log('readStatus:'+v);
			STATUS_JSON = scriptJQ.evalJSON(v);
			console.log('readStatus  2: '+scriptJQ.toJSON(STATUS_JSON));
			callBack(STATUS_JSON);
		});
	} else {
		GM_log('config:'+GM_getValue(KEY_CONFIG, '{write:1}'));
		try {
			config = JSON.parse(GM_getValue(KEY_CONFIG, '{write:1}'));	
		} catch (e) {
			config = {write:1};
		}
		
		if (refresh(config, 1800)) {
			GM_xmlhttpRequest({method: 'GET',
			     url: 'http://cms.edit.naviextras.com/opencms/opencms/shop/helper/config.json?time='+(new Date()).getTime(),
			     headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
			              'Accept': 'application/json'
				 },
				 onload: function(responseDetails) {
					var data = responseDetails.responseText;
                    GM_log('readVersion.onLoad');
					CONFIG_JSON = JSON.parse(data);
					CONFIG_JSON.write = (new Date()).getTime()
					GM_setValue(KEY_CONFIG, scriptJQ.toJSON(CONFIG_JSON));
					callBack(CONFIG_JSON);
				 },
                 onerror: function(responseDetails) {
                    GM_log(scriptJQ.toJSON(responseDetails));
                    callBack(config);
                 }
			});
		} else {
			GM_log('hold fire');
			callBack(config);
		}
	};
	//return CONFIG_JSON;
}

function readConfigCallback() {
	readConfig(function (v) {
		config = v;
		try {
			realMain();
		} catch (e) {
			console.log(e);
		}
	});
}

function readVersionCallback() {
	readVersion(function (v) {
		var html = "";
		var lastFirefoxVersion = null;
		var accordionCount = 0;
		var count = 0;
		for(var key in v.changeLog) {
			var cl = v.changeLog[key];
			html += '<h3><a href="javascript:void()">'+key+' ('+cl.date+')</a></h3><div><ul>';
			if (!isChrome && cl.firefox) {
				html += '<a href="'+v.base+cl.firefox+'" '+
				(!isChrome && isNewerVersion(parseVersion(GM_getValue('versionPopup',VERSION_STR)), parseVersion(key))
				? 'style="color:red; font-weight:bold;"' : '')
				+'>Version: '+key+'</a><br/>';
			}
			for(var l in cl.lines) {
				html += '<li>'+cl.lines[l].li+'</li>';
				if (cl.lines[l].p != undefined) {
					html += '<p align="justify">'+cl.lines[l].p+'</p>';
				}
			}
			html += '</ul></div>';
			if (!isChrome && lastFirefoxVersion == null && cl.firefox != undefined) {
				lastFirefoxVersion  = key;
				accordionCount = count;
			}
			count ++;
		}
		scriptJQ( "#nngChangeLog" ).accordion("destroy");
		scriptJQ( "#nngChangeLog" ).html(html);
		scriptJQ( "#nngChangeLog" ).accordion({
			event: "mouseover",
			autoHeight: false
		});
		if (!isChrome) {
			if (isNewerVersion(parseVersion(GM_getValue('versionPopup',VERSION_STR)), parseVersion(lastFirefoxVersion))) {
				GM_setValue('versionPopup',lastFirefoxVersion);
				scriptJQ( "#nngChangeLog" ).accordion("",accordionCount);
				showAdminTab(TAB_CHANGELOG);
			}
			if (isNewerVersion(VERSION, parseVersion(lastFirefoxVersion))) {
				scriptJQ( "#nngTrackedVersion").css('color','red').css('font-weight','bold');
			}
		}
	});	
}

function refresh(o, sec) {
	var now = (new Date()).getTime();
	if (!sec) {sec = 0;}
	return o && o.write && ((sec*1000)< (now-o.write));
}

function readOptions() {
	var ops =  eval('('+getValue(KEY_OPTIONS,'{}')+')');
	if (ops.projects == undefined) {
		ops.projects = ops.prods;
	}
	for(o in optionsDefault) {
		if (ops[o]==null) {
			ops[o] = optionsDefault[o];
		}
	}
	options = ops;
}

function writeOptions(options) {
	delete options.prods;
	GM_log('writeOptions:'+scriptJQ.toJSON(options));
	setValue(KEY_OPTIONS,scriptJQ.toJSON(options));
}

function padd(number) {
	var s = '00'+number;
	return s.substr(s.length-2,2);
}

function  date2myTime(date) {
	var result = {};
	result.date = date.getFullYear()+'-'+padd(date.getMonth()+1)+'-'+padd(date.getDate());
	result.time = padd(date.getHours())+':'+padd(date.getMinutes());
	return result;
}

function myTime(value) {
	var result = {};
	if(!TIME_PATTERN.test(value)) {
		result.status = 1; // WRONG FORMAT
	} else {
		var m = TIME_PATTERN.exec(value);
		result.hour = m[1]*1;
		result.minute = m[2]*1;
		result.sum = result.hour*60 + result.minute;
		result.formatted = padd(result.hour)+":"+padd(result.minute);
		if (result.hour < 0) {
			result.status = 2; // LESS HOUR
		} else if(result.hour>23) {
			result.status = 3; // MORE HOUR
		} else if (result.minute < 0) {
			result.status = 4; // LESS MIN
		} else if(result.minute>59) {
			result.status = 5; // MORE MIN
		} else {
			result.status = 0; // OK
		}
	}
	return result;
}

function floatingMessage(str, adminOnly, p) {
	if (!adminOnly || options.adminMessages ) {
		p = p == undefined ? {time: 5000} : p;
		if (p.time == undefined) {
			p.time = 5000;
		}
		scriptJQ.floatingMessage( str, p);
	}
}

function myDate(str) {
	var m = /(\d{4})-(\d{2})-(\d{2})/.exec(str);
	return new Date(m[1]*1,m[2]*1-1,m[3]*1);
}

function initShopAdmin(parts) {
}

function initNavteq(parts) {
	console.log('initNavteq'+parts[5]);
	if (location.href.indexOf("ViewData-Start")>0) {
		scriptJQ('#CreditCardNumber').attr('value','4111111111111111');
		scriptJQ('#CreditCardOwner').attr('value','Teszt Elek');
		scriptJQ('#CreditCardCVC').attr('value','111');
		scriptJQ('#CreditCardExpiryMonth option:eq(2)').attr('selected','selected');
		scriptJQ('#CreditCardExpiryYear option:eq(2)').attr('selected','selected');
	}
}

function initBibit(parts) {
	console.log('initBibit'+parts[5]);
	if (parts[5].indexOf("MC_SSLController.jsp")==0 || parts[6].indexOf("MC_SSLController.jsp")==0) {
		scriptJQ('#cardNumber').attr('value','5454545454545454');
		scriptJQ('#cardHolderName').attr('value','Teszt Elek');
		scriptJQ('#CVC').attr('value','111');
		scriptJQ('select[name="expiryMonth"] option:eq(2)').attr('selected','selected');
		scriptJQ('select[name="expiryYear"] option:eq(2)').attr('selected','selected');
	}
}

function showSystem(ip, hostPart) {
	var parts = hostPart.split(':');
	var host = hostPart.toLowerCase();
	var port = 0;
	if (parts.length == 2) {
		host = parts[0].toLowerCase();
		port = parts[1]*1;
		if (port == 443 || port == 80) {
			port = 0;
		} 
	}
	findSystem(host, port, ip);
}

var	system="???";
var server="???";
function findSystem(host, port, ip) {
	//console.log('findSystem:'+host+','+ port+','+ ip);
	var res = (/(.*)\.navngo\.local$/g).exec(host);
	if (res) {
		system="developer";
		server=res[1];
		scriptJQ('#system').text(system);
		scriptJQ('#server').text(server);
		site = 'navngo.local';
	} else if (port) {
		for( var sys in config.systems) {
			for( var ser in config.systems[sys].servers) {
				var p = new RegExp(config.systems[sys].servers[ser].host.replace(/\./,"\\.")+'$','i');
				if (host.match(p)) {
					for (var p in  config.systems[sys].servers[ser].ports) {
						if (port == config.systems[sys].servers[ser].ports[p]) {
							site = config.systems[sys].base;
							system=sys;
							server=ser;
							scriptJQ('#system').text(sys);
							scriptJQ('#server').text(server);
							return;
						}
					}
				}
			}
		}	
	} else {
		for( var sys in config.systems) {
			var p = new RegExp(config.systems[sys].base.replace(/\./,"\\.")+'$','i');
			if (host.match(p)) {
				scriptJQ('#system').text(sys);
				site = config.systems[sys].base;
				system=sys;
				for( var ser in config.systems[sys].servers) {
					//console.log('ser:'+ser);
					if (ip*1 == config.systems[sys].servers[ser].ip) {
						scriptJQ('#server').text(ser);
						server=ser;
						return;
					}
				}
				return;
			}
		}
	}
}

function editCMS() {
	var id = scriptJQ(this).attr('res').replace(/\//g,"%2f").replace(/\$/g,"%24");
	window.open('http://cms.edit.naviextras.com/opencms/opencms/system/workplace/editors/editor.jsp?resourcelist=&resource='+id);
	ev.preventDefault();
	return false;
}
var nestate = '';

function showContentInfo() {
	var CMS = scriptJQ(this);
	
	scriptJQ('#cmsDialog').html('<table width="100%"><tr><th align="right">Key</th><td align="left" style="padding-left:10px">'+CMS.attr('liveid')+'</td></tr>'
		+'<tr><th align="right">Channel</th><td align="left" style="padding-left:10px">'+CMS.attr('channel')+'</td></tr>'
		+'<tr><th align="right">Part</th><td align="left" style="padding-left:10px">'+CMS.attr('part')+'</td></tr>'
		+'<tbody id="cmsversions">'
		+'<tr><td colspan="2" align="center"><img src="/shopAdmin/images/wait.gif"/>LOADING CMS information<img src="/shopAdmin/images/wait.gif"/></td></tr>'
		+'</tbody></table>'
		);
	if (isChrome) {
		scriptJQ.ajax( {
			url: "http://cms.edit.naviextras.com/opencms/opencms/shop/helper/ajax",
			data: {id:CMS.attr('liveid')},
			dataType: 'json',
			success: function(data) {
				var s = "<tr><th align='right'>Channel</th><th align='left' style='padding-left:10px'>Languages</th><tr>";
				for(var c in data) {
					s += "<tr><td class='contentChannel' liveid='"+CMS.attr('liveid')
					+"' res='"+data[c].res+"' channel='"+data[c].channel+"' align='right'>"
					+data[c].channel+"</td><td align='left' style='padding-left:10px' title='"
					+scriptJQ.toJSON(data[c].langs)+"'>"+data[c].langs.length+" language(s)</td><tr>";
				}
				scriptJQ('#cmsversions').html(s);
				scriptJQ('#cmsversions .contentChannel')
				.css('text-decoration','underline')
				.css('cursor','pointer')
				.click(editCMS);
			},
			error: function(data,status,err) {
				scriptJQ('#cmsversions').html('<span style="color:red; font-weight: bold">FAILED!!! "'+status+'":"'+err	+'"</span>');
			}
		});
	} else {
		GM_xmlhttpRequest( {
			method: 'GET',
			data: "id="+CMS.attr('liveid'),
			url: "http://cms.edit.naviextras.com/opencms/opencms/shop/helper/ajax",
			headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
			'Accept': 'application/json'
		}, onload: function(responseDetails) {
			var data = eval('('+responseDetails.responseText+')')
				var s = "<tr><th align='right'>Channel</th><th align='left' style='padding-left:10px'>Languages</th><tr>";
				for(var c in data) {
					s += "<tr><td class='contentChannel' liveid='"+CMS.attr('liveid')
					+"' res='"+data[c].res+"' channel='"+data[c].channel+"' align='right'>"
					+data[c].channel+"</td><td align='left' style='padding-left:10px' title='"
					+scriptJQ.toJSON(data[c].langs)+"'>"+data[c].langs.length+" language(s)</td><tr>";
				}
				scriptJQ('#cmsversions').html(s);
				scriptJQ('#cmsversions .contentChannel')
				.css('text-decoration','underline')
				.css('cursor','pointer')
				.click(editCMS);
		}, onerror: function(responseDetails) {
			scriptJQ('#cmsversions').html('<span style="color:red; font-weight: bold">FAILED!!! "'+status+'":"'+err	+'"</span>');
			GM_log(scriptJQ.toJSON(responseDetails));
		}
		});
	};
	
	scriptJQ('#cmsDialog').dialog( "open" );
	return false;
}
var config = {
	languages: {
		"zh":"Chinese",
		"hr":"Croatian",
		"cs":"Czech",
		"en":"English",
		"fr":"French",
		"de":"German",
		"el":"Greek",
		"hu":"Hungarian",
		"it":"Italian",
		"pl":"Polish",
		"pt":"Portuguese",
		"ro":"Romanian", 
		"ru":"Russian",
		"sk":"Slovak",
		"sl":"Slovenian",
		"es":"Spanish",
		"tr":"Turkish",
		"ua":"Ukrainian (ua)",
		"uk":"Ukrainian (uk)",
		"th":"Thai"
	},
    channels: {
		"www" : ["naviextras.com"],
		"airis" : ["airis"],
		"telesystem" : ["telesystem"],
		"motorola" : ["motorola"],
		"dacia" : ['linefit-dacia-eu'],
		"renault" : ['linefit-renault-eu']
	}, systems : { 
		"iop" :	{ 
			base : "iop.demo.naviextras.com",
			servers : {
				'bike' : { ip : 106, host : 'bike1.dev.naviextras.com', ports:[11080,11081], usr: 'extrone' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "beta" : { 
			base : "beta.demo.naviextras.com",
			servers : {
				'bike': { ip : 106, host : 'bike1.dev.naviextras.com', ports: [11280,11281], usr: 'extwo' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "early" : { 
			base : "early.demo.naviextras.com",
			servers : {
				'bike': { ip : 106, host : 'bike1.dev.naviextras.com', ports: [11080,11081], usr: 'extra' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "snapshot" : { 
			base : "snapshot.dev.naviextras.com",
			servers : {
				 'parcae': { ip : 154,  host : 'parcae.dev.naviextras.com', ports:[11080,11081], usr: 'extra' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "inquisitor" : { 
			base : "inquisitor.dev.naviextras.com",
			servers : {
				'elvin1' : { ip : 154, host : 'elvin1.dev.naviextras.com', ports:[11180,11181], usr: 'extra' },
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "pool" : { 
			base : "pool.dev.naviextras.com",
			servers : {
				'gaia' : { ip : 151, host : 'elvin1.dev.naviextras.com', ports:[11180,11181], usr: 'extrone' },
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "licenseTest" : { 
			base : "license.test.naviextras.com",
			servers : {
				'gina' :{ ip : 10, host : 'gina1.naviextras.com', ports:[14080,14081], usr: 'hixtra' },
				'grace' : { ip : 138, host : 'grace1.naviextras.com', ports:[14080,14081], usr: 'hixtra' },
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "test" : { 
			base : "test.naviextras.com",
			servers : {
				'edward' : { ip : 69, host : 'edward1.dev.naviextras.com', ports:[11080,11081], usr: 'extra' },
				'elvin1' : { ip : 85, host : 'elvin1.dev.naviextras.com', ports:[11080,11081], usr: 'extra' },
				'florin1' : { ip : 70, host : 'florin1.dev.naviextras.com', ports:[11080,11081], usr: 'extra' },
				'frodo1' : { ip : 86, host : 'frodo1.dev.naviextras.com', ports:[11080,11081], usr: 'extra' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "devsup" : { 
			base : "devsup.edit.naviextras.com",
			servers : {
				'europa' : { ip : 152, host : 'europa.local.naviextras.com', ports:[11180,11181], usr: 'extrone' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "edit" : { 
			base : "edit.naviextras.com",
			servers : {
				'europa' : { ip : 152, host : 'europa.local.naviextras.com', ports:[11080,11081], usr: 'extra' }
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "developer" : { 
			base : "navngo.local",
			servers : {},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "license" : { 
			base : "license.naviextras.com",
			servers : {
				'gina' :{ ip : 10, host : 'gina1.naviextras.com', ports:[14080,14081], usr: 'hixtra' },
				'grace' : { ip : 138, host : 'grace1.naviextras.com', ports:[14080,14081], usr: 'hixtra' },
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		} , "production" : { 
			base : "naviextras.com",
			servers : {
				'frida' :{ ip : 137, host : 'frida.naviextras.com', ports:[11080,11081], usr: 'extra' },
				'erin' : { ip : 8, host : 'erin.naviextras.com', ports:[11080,11081], usr: 'extra' },
				'esther' : { ip : 136, host : 'esther.naviextras.com', ports:[11080,11081], usr: 'extra' },
			},
			db : {host: 'dbhost??', usr: 'usr???', port: 5432, prefix : 'prefix???'}
		}
	}
};



/*!
 * jQuery Cookie Plugin v1.4.0
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2013 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as anonymous module.
		define(['jquery'], factory);
	} else {
		// Browser globals.
		factory(jQuery);
	}
}(function ($) {

	var pluses = /\+/g;

	function encode(s) {
		return config.raw ? s : encodeURIComponent(s);
	}

	function decode(s) {
		return config.raw ? s : decodeURIComponent(s);
	}

	function stringifyCookieValue(value) {
		return encode(config.json ? JSON.stringify(value) : String(value));
	}

	function parseCookieValue(s) {
		if (s.indexOf('"') === 0) {
			// This is a quoted cookie as according to RFC2068, unescape...
			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
		}

		try {
			// Replace server-side written pluses with spaces.
			// If we can't decode the cookie, ignore it, it's unusable.
			s = decodeURIComponent(s.replace(pluses, ' '));
		} catch(e) {
			return;
		}

		try {
			// If we can't parse the cookie, ignore it, it's unusable.
			return config.json ? JSON.parse(s) : s;
		} catch(e) {}
	}

	function read(s, converter) {
		var value = config.raw ? s : parseCookieValue(s);
		return $.isFunction(converter) ? converter(value) : value;
	}

	var config = $.cookie = function (key, value, options) {

		// Write
		if (value !== undefined && !$.isFunction(value)) {
			options = $.extend({}, config.defaults, options);

			if (typeof options.expires === 'number') {
				var days = options.expires, t = options.expires = new Date();
				t.setDate(t.getDate() + days);
			}

			return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path    ? '; path=' + options.path : '',
				options.domain  ? '; domain=' + options.domain : '',
				options.secure  ? '; secure' : ''
			].join(''));
		}

		// Read

		var result = key ? undefined : {};

		// To prevent the for loop in the first place assign an empty array
		// in case there are no cookies at all. Also prevents odd result when
		// calling $.cookie().
		var cookies = document.cookie ? document.cookie.split('; ') : [];

		for (var i = 0, l = cookies.length; i < l; i++) {
			var parts = cookies[i].split('=');
			var name = decode(parts.shift());
			var cookie = parts.join('=');

			if (key && key === name) {
				// If second argument (value) is a function it's a converter...
				result = read(cookie, value);
				break;
			}

			// Prevent storing a cookie that we couldn't decode.
			if (!key && (cookie = read(cookie)) !== undefined) {
				result[name] = cookie;
			}
		}

		return result;
	};

	config.defaults = {};

	$.removeCookie = function (key, options) {
		if ($.cookie(key) !== undefined) {
			// Must not alter options, thus extending a fresh object...
			$.cookie(key, '', $.extend({}, options, { expires: -1 }));
			return true;
		}
		return false;
	};

}));